// internal/apps/auth/services/role_service.go
package services

import (
	"errors"
	"fmt"
	"star-go-app/internal/apps/auth/models"
	"star-go-app/internal/apps/auth/repositories"
	"star-go-app/internal/apps/auth/serializers"

	"gorm.io/gorm"
)

// RoleService 角色服务接口
type RoleService interface {
	// 基本CRUD操作
	CreateRole(req *serializers.CreateRoleRequest) (*serializers.RoleResponse, error)
	GetRoleByID(id uint) (*serializers.RoleResponse, error)
	UpdateRole(id uint, req *serializers.UpdateRoleRequest) (*serializers.RoleResponse, error)
	UpdateRoleWhole(id uint, req *serializers.UpdateRoleWholeRequest) (*serializers.RoleResponse, error)
	DeleteRole(id uint) error

	// 列表查询
	GetRoleList(req *serializers.RoleListRequest) (*serializers.RoleListResponse, error)

	// 永久删除角色
	DeleteRolePermanently(id uint) error
}

// roleService 角色服务实现
type roleService struct {
	roleRepo repositories.RoleRepository
}

// NewRoleService 创建角色服务实例
func NewRoleService() RoleService {
	return &roleService{
		roleRepo: repositories.NewRoleRepository(),
	}
}

// CreateRole 创建角色
func (s *roleService) CreateRole(req *serializers.CreateRoleRequest) (*serializers.RoleResponse, error) {
	// 检查角色编码是否已存在
	exists, err := s.roleRepo.IsRoleCodeExists(req.Code)
	if err != nil {
		return nil, fmt.Errorf("检查角色编码失败: %v", err)
	}
	if exists {
		return nil, errors.New("角色编码已存在")
	}

	// 检查角色名称是否已存在
	exists, err = s.roleRepo.IsRoleNameExists(req.Name)
	if err != nil {
		return nil, fmt.Errorf("检查角色名称失败: %v", err)
	}
	if exists {
		return nil, errors.New("角色名称已存在")
	}

	// 创建角色模型
	role := &models.Role{
		Name:        req.Name,
		Code:        req.Code,
		Description: req.Description,
		Permissions: models.Permissions(req.Permissions),
	}

	// 保存到数据库
	if err := s.roleRepo.CreateRole(role); err != nil {
		return nil, fmt.Errorf("创建角色失败: %v", err)
	}

	// 转换并返回响应
	return serializers.ConvertRoleToResponse(role), nil
}

// GetRoleByID 根据ID获取角色
func (s *roleService) GetRoleByID(id uint) (*serializers.RoleResponse, error) {
	role, err := s.roleRepo.GetRoleByID(id)
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, errors.New("角色不存在")
		}
		return nil, fmt.Errorf("获取角色失败: %v", err)
	}

	return serializers.ConvertRoleToResponse(role), nil
}

// UpdateRole 部分更新角色
func (s *roleService) UpdateRole(id uint, req *serializers.UpdateRoleRequest) (*serializers.RoleResponse, error) {
	// 获取现有角色
	role, err := s.roleRepo.GetRoleByID(id)
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, errors.New("角色不存在")
		}
		return nil, fmt.Errorf("获取角色失败: %v", err)
	}

	// 检查角色编码是否重复
	if req.Code != nil && *req.Code != role.Code {
		exists, err := s.roleRepo.IsRoleCodeExists(*req.Code, id)
		if err != nil {
			return nil, fmt.Errorf("检查角色编码失败: %v", err)
		}
		if exists {
			return nil, errors.New("角色编码已存在")
		}
		role.Code = *req.Code
	}

	// 检查角色名称是否重复
	if req.Name != nil && *req.Name != role.Name {
		exists, err := s.roleRepo.IsRoleNameExists(*req.Name, id)
		if err != nil {
			return nil, fmt.Errorf("检查角色名称失败: %v", err)
		}
		if exists {
			return nil, errors.New("角色名称已存在")
		}
		role.Name = *req.Name
	}

	// 更新其他字段
	if req.Description != nil {
		role.Description = *req.Description
	}
	if req.Permissions != nil {
		role.Permissions = models.Permissions(*req.Permissions)
	}

	// 保存更新
	if err := s.roleRepo.UpdateRole(role); err != nil {
		return nil, fmt.Errorf("更新角色失败: %v", err)
	}

	return serializers.ConvertRoleToResponse(role), nil
}

// UpdateRoleWhole 完整更新角色
func (s *roleService) UpdateRoleWhole(id uint, req *serializers.UpdateRoleWholeRequest) (*serializers.RoleResponse, error) {
	// 获取现有角色
	role, err := s.roleRepo.GetRoleByID(id)
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, errors.New("角色不存在")
		}
		return nil, fmt.Errorf("获取角色失败: %v", err)
	}

	// 检查角色编码是否重复
	if req.Code != role.Code {
		exists, err := s.roleRepo.IsRoleCodeExists(req.Code, id)
		if err != nil {
			return nil, fmt.Errorf("检查角色编码失败: %v", err)
		}
		if exists {
			return nil, errors.New("角色编码已存在")
		}
	}

	// 检查角色名称是否重复
	if req.Name != role.Name {
		exists, err := s.roleRepo.IsRoleNameExists(req.Name, id)
		if err != nil {
			return nil, fmt.Errorf("检查角色名称失败: %v", err)
		}
		if exists {
			return nil, errors.New("角色名称已存在")
		}
	}

	// 更新所有字段
	role.Name = req.Name
	role.Code = req.Code
	role.Description = req.Description
	role.Permissions = models.Permissions(req.Permissions)

	// 保存更新
	if err := s.roleRepo.UpdateRole(role); err != nil {
		return nil, fmt.Errorf("更新角色失败: %v", err)
	}

	return serializers.ConvertRoleToResponse(role), nil
}

// DeleteRole 删除角色
func (s *roleService) DeleteRole(id uint) error {
	// 检查角色是否存在
	_, err := s.roleRepo.GetRoleByID(id)
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return errors.New("角色不存在")
		}
		return fmt.Errorf("获取角色失败: %v", err)
	}

	// TODO: 检查是否有用户使用该角色
	// 这里可以添加业务逻辑检查是否有用户关联该角色

	// 删除角色
	if err := s.roleRepo.DeleteRole(id); err != nil {
		return fmt.Errorf("删除角色失败: %v", err)
	}

	return nil
}

// GetRoleList 获取角色列表
func (s *roleService) GetRoleList(req *serializers.RoleListRequest) (*serializers.RoleListResponse, error) {
	// 设置默认值
	if req.Page <= 0 {
		req.Page = 1
	}
	if req.PageSize <= 0 {
		req.PageSize = 10
	}
	if req.PageSize > 100 {
		req.PageSize = 100
	}

	// 获取角色列表
	roles, total, err := s.roleRepo.GetRoleList(req)
	if err != nil {
		return nil, fmt.Errorf("获取角色列表失败: %v", err)
	}

	// 转换响应
	roleResponses := serializers.ConvertRolesToResponse(roles)

	return &serializers.RoleListResponse{
		List:     roleResponses,
		Total:    total,
		Page:     req.Page,
		PageSize: req.PageSize,
	}, nil
}

// DeleteRolePermanently 永久删除角色
func (s *roleService) DeleteRolePermanently(id uint) error {
	return s.roleRepo.DeleteRolePermanently(id)
}
